<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>递归复制</title>
</head>
<body>

</body>
<script>
    function deepClone(value, map = new WeakMap()) {
            // 如果是原始值（null, undefined, number, string, boolean, symbol）
            if (value === null || typeof value !== 'object') {
                return value;
            }

            // 如果是函数，直接返回
            if (typeof value === 'function') {
                return value;
            }

            // 如果是正则表达式，直接返回新的正则对象
            if (value instanceof RegExp) {
                return new RegExp(value);
            }

            // 如果是日期，直接返回新的日期对象
            if (value instanceof Date) {
                return new Date(value);
            }
            if (typeof value === 'symbol' || typeof value === 'undefined') {
                console.log('---', value)
                return value
            }

            // 处理循环引用，防止死循环
            if (map.has(value)) {
                return map.get(value);
            }

            const result = Array.isArray(value) ? [] : Object.create(Object.getPrototypeOf(value));

            // 记录已经拷贝的对象
            map.set(value, result);

            // 拷贝对象的每一个属性
            for (const key of Reflect.ownKeys(value)) {
                if (value.hasOwnProperty(key)) {
                    result[key] = deepClone(value[key], map);
                }
            }

            return result;
         }

    function Test () {
        this.a = 1
        this.b =2
    }
    const test = new Test()
    Test.prototype.c = 3
    // 测试代码
    const obj = {
        a: 1,
        b: [1, 2, 3],
        c: {
            d: 4,
            e: new Date(),
            f: /abc/g
        },
        test: test
    };
    obj.g = obj; // 循环引用

    const clonedObj = deepClone(obj);
    console.log(clonedObj);
    console.log('test', test)
</script>
</html>